package com.graduationproject.service.Impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.graduationproject.Util.RedisUtil;
import com.graduationproject.entity.*;
import com.graduationproject.entity.dto.DishUserDTO;
import com.graduationproject.mapper.DishMakeMapper;
import com.graduationproject.mapper.DishMapper;
import com.graduationproject.service.DishService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;


import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author shkstart
 * @create 2023-12-04-14:29
 */
@Service
public class DishServiceImpl extends ServiceImpl<DishMapper, Dish> implements DishService {

    @Autowired
    private DishMapper dishMapper;

    @Autowired
    private DishMakeMapper dishMakeMapper;

    @Autowired
    private RedisUtil redis;

    @Override
    public Dish findDishById(Integer id) {
        Dish dishById = baseMapper.selectById(id);
        LambdaQueryWrapper<DishMake> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DishMake :: getDish_id, dishById.getId());
        DishMake dishMake = dishMakeMapper.selectOne(queryWrapper);
        dishById.setMakes(dishMake.getMakes());
        return dishById;
    }

    @Override
    public List<Dish> findDishesAll() {
        List<Dish> dishesAll = (List<Dish>)redis.get("dishAll");
        return dishesAll;
    }

    @Override
    public List<Dish> search(String input) {
        List<Dish> dishesAll = (List<Dish>)redis.get("dishAll");
        List<Dish> search = dishesAll.stream().map(item -> {
            String dishName = item.getDishName();
            boolean contains = dishName.contains(input);
            if (contains){
                return item;
            }else return null;
        }).collect(Collectors.toList());
        return search;
    }

    @Override
    public List<Dish> searchHotDishes(Integer type) {
        List<Dish> dishesAll = (List<Dish>)redis.get("dishAll");
        List<Dish> hotDishes = dishesAll.stream().map(item -> {
            if (item.getDishType().equals(String.valueOf(type))) {
                return item;
            } else return null;
        })
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
//        List<Dish> hotDishes = dishMapper.searchHotDishes(type);
        //菜品类型转义
        for (Dish dish : hotDishes) {
            if ("1".equals(dish.getDishType())) {
                dish.setDishType("热菜");
            } else if ("2".equals(dish.getDishType())) {
                dish.setDishType("凉菜");
            } else if ("3".equals(dish.getDishType())) {
                dish.setDishType("汤羹");
            } else if ("4".equals(dish.getDishType())) {
                dish.setDishType("主食");
            }
        }
        return hotDishes;
    }

    @Override
    public PageResult<Dish> findDishPage() {
        List<Dish> byPage = dishMapper.findByPage();
        for (Dish dish : byPage) {
            if ("1".equals(dish.getDishType())) {
                dish.setDishType("热菜");
            } else if ("2".equals(dish.getDishType())) {
                dish.setDishType("凉菜");
            } else if ("3".equals(dish.getDishType())) {
                dish.setDishType("汤羹");
            } else if ("4".equals(dish.getDishType())) {
                dish.setDishType("主食");
            }
        }
        PageResult<Dish> pageResult = new PageResult<>(byPage);
        return pageResult;
    }

    @Override
    public String findTotals() {
        String totals = dishMapper.findTotals();
        return totals;
    }

    @Override
    public void deleteDish(int row) {
        baseMapper.deleteById(row);
        //删除菜品制作表
        QueryWrapper<DishMake> dishMakeQueryWrapper = new QueryWrapper<>();
        dishMakeQueryWrapper.eq("dish_id", row);
        dishMakeMapper.delete(dishMakeQueryWrapper);
    }

    @Override
    public Dish findAllById(Integer id) {
//        List<Dish> allById = dishMapper.findAllById(id);
        List<Dish> dishesAll = (List<Dish>)redis.get("dishAll");
        List<Dish> allById = dishesAll.stream().map(item -> {
            if (item.getId() == id) {
                return item;
            } else return null;
        })
                .filter(Objects :: nonNull)
                .collect(Collectors.toList());
        Dish dish = allById.get(0);
        if ("1".equals(dish.getDishType())) {
            dish.setDishType("热菜");
        } else if ("2".equals(dish.getDishType())) {
            dish.setDishType("凉菜");
        } else if ("3".equals(dish.getDishType())) {
            dish.setDishType("汤羹");
        } else if ("4".equals(dish.getDishType())) {
            dish.setDishType("主食");
        }
        return dish;
    }

    @Override
    public void dishPut(Dish dish) {
        dishMapper.dishPut(dish);
    }

    @Override
    public void dishMakePut(DishMake dishMakes) {
        dishMapper.dishMakePut(dishMakes);
    }

    @Override
    public void addDishAndMake(Dish dish) {
        dishMapper.addDishAndMake(dish);
    }

    @Override
    public void addDishMake(DishMake dishMake) {
        dishMapper.addDishMake(dishMake);
    }

    @Override
    public ArrayList<Dish> matchDish(String number, String sum) {
        //查询全部菜品信息
        List<Dish> dishesAll = (List<Dish>)redis.get("dishAll");
        //将热量遍历出来存入集合
        ArrayList<Integer> dishHeat = new ArrayList<>();
        for(Dish dish : dishesAll) {
            dishHeat.add(Integer.parseInt(dish.getHeat()));
        }
        int num = Integer.parseInt(number);
        int sums = Integer.parseInt(sum);
        //调用方法获取匹配的菜品id
        List<Integer> result = findClosestSum(dishHeat, num, sums);
        //根据菜品id查询菜品信息返回
        ArrayList<Dish> dishes = new ArrayList<>();
        for(int i=0;i<result.size();i++){
            Integer dishId = result.get(i);
            Dish dishById = baseMapper.selectById(dishId);
            String dishType = dishById.getDishType();
            if("1".equals(dishType)){
                dishById.setDishType("热菜");
            }else if("2".equals(dishType)){
                dishById.setDishType("凉菜");
            }else if("3".equals(dishType)){
                dishById.setDishType("汤羹");
            }else if("4".equals(dishType)){
                dishById.setDishType("主食");
            }
            dishes.add(dishById);
        }
        return dishes;
    }

    @Override
    public void addDishRecord(List<Dish> dishes, String username) {
        DishRecord dishRecord = new DishRecord();
        dishRecord.setDishUser(username);
        for(Dish dish: dishes){
            Date date = new Date();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String formattedDate = sdf.format(date);
            dishRecord.setTime(formattedDate);
            dishRecord.setDishId(dish.getId());
            dishRecord.setDishName(dish.getDishName());
            dishRecord.setDishType(dish.getDishType());
            dishRecord.setFat(dish.getFat());
            dishRecord.setHeat(dish.getHeat());
            dishRecord.setCarbohydrates(dish.getCarbohydrates());
            dishRecord.setProtein(dish.getProtein());
            dishMapper.addDishRecord(dishRecord);
        }
    }

    @Override
    public List<DishRecord> getDishRecord(String username) {
        List<DishRecord> dishRecord = dishMapper.getDishRecord(username);
        return dishRecord;
    }

    @Override
    public List<DishRecord> findByTime(String startTime,String endTime,String username) {
        List<DishRecord> dishRecord = dishMapper.findByTime(startTime,endTime,username);
        return dishRecord;
    }

    @Override
    public int findDishByTime(String startTime, String endTime, String username) {
        int sum=0;
        int[] heatByTime = dishMapper.findHeatByTime(startTime, endTime, username);
            for (int i = 0; i < heatByTime.length; i++) {
                sum += heatByTime[i];
            }

        return sum;

    }

    @Override
    public List<Dish> getCarouselChart() {
        return dishMapper.getCarouselChart();
    }

    private static List<Integer> findClosestSum(ArrayList<Integer> numbers,int num,int sums){
        if (num > numbers.size()) {
            System.out.println("抽取的数目超过了数组长度！");
            return null;
        }
        List<Integer> closestCombination = new ArrayList<>();
        int closestSum = Integer.MAX_VALUE; //获取int类型最大值
        //获取最接近目标的菜品id集合
        for (int i = 0; i < 10000; i++) {
            Random random = new Random();
            List<Integer> selection = new ArrayList<>();
            ArrayList<Integer> dishesId = new ArrayList<>();
            //随机生成菜品id，并获取到菜品热量
            while (selection.size() < num) {
                int index = random.nextInt(numbers.size());
                int nums = numbers.get(index);
                if(selection.contains(index)){
                    continue;
                }else {
                    selection.add(nums);
                    dishesId.add(index);
                }
            }
            //计算获取到的菜品热量的总和
            int sum = selection.stream().mapToInt(Integer::intValue).sum();
            //获取最接近的菜品id组合
            if (Math.abs(sum - sums) < Math.abs(closestSum - sums)) {
                ArrayList<Integer> integers = new ArrayList<>();
                for(int i1 : dishesId) {
                    i1++;
                    integers.add(i1);
                }
                closestSum = sum;
                closestCombination = new ArrayList<>(integers);
            }
        }
        return closestCombination;
    }

    public List<Dish> selectDishAndMake() {
        return dishMapper.selectDishAndMake();
    }


}


